package com.gmt;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.List;

/**
 * @author John.zhang
 * @version Id: GmDefineIpHashRule, v 1.0 2020/11/17 17:15 ZhiYong Exp $
 */
public class GmDefineIpHashRule extends AbstractLoadBalancerRule {

    Logger logger = LoggerFactory.getLogger(GmDefineIpHashRule.class);

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {
        return choose(getLoadBalancer(), o);
    }

    public Server choose(ILoadBalancer iLoadBalancer, Object key) {
        logger.info("GmDefineIpHashRule" + key);
        if (iLoadBalancer == null) {
            return null;
        }
        //获取可用服务实例列表
        List<Server> reachableServers = iLoadBalancer.getReachableServers();
        //获取所有服务实例列表
        List<Server> allServers = iLoadBalancer.getAllServers();
        if (allServers.size() == 0) {
            return null;
        }
        int i = ipAddressHash(allServers.size());
        return reachableServers.get(i);
    }


    private int ipAddressHash(int serverCount) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String remoteAdar = requestAttributes.getRequest().getRemoteAddr();
        int code = Math.abs(remoteAdar.hashCode());
        return code % serverCount;
    }

}
